package com.castle.fortress.admin.orders.service.impl;

import cn.hutool.core.util.StrUtil;
import com.alipay.api.domain.Goods;
import com.castle.fortress.admin.goods.dto.GoodsDto;
import com.castle.fortress.admin.goods.entity.GoodsEntity;
import com.castle.fortress.admin.goods.entity.GoodsOptionEntity;
import com.castle.fortress.admin.goods.service.GoodsOptionService;
import com.castle.fortress.admin.goods.service.GoodsService;
import com.castle.fortress.admin.member.entity.MemberGoodsCartEntity;
import com.castle.fortress.admin.member.service.MemberGoodsCartService;
import com.castle.fortress.admin.orders.dto.GoodsOrderItemDto;
import com.castle.fortress.admin.orders.entity.GoodsOrderItemEntity;
import com.castle.fortress.admin.orders.entity.SaleCouponDataEntity;
import com.castle.fortress.admin.orders.entity.SaleCouponEntity;
import com.castle.fortress.admin.orders.enums.CouponBackTypeEnum;
import com.castle.fortress.admin.orders.enums.CouponStatusEnum;
import com.castle.fortress.admin.orders.service.GoodsOrderItemService;
import com.castle.fortress.admin.orders.service.SaleCouponDataService;
import com.castle.fortress.admin.orders.service.SaleCouponService;
import com.castle.fortress.admin.utils.BizCommonUtil;
import com.castle.fortress.common.enums.OrderInsideStatusEnum;
import com.castle.fortress.common.enums.OrderStatusEnum;
import com.castle.fortress.common.exception.BizException;
import com.castle.fortress.common.respcode.GlobalRespCode;
import com.castle.fortress.common.utils.ConvertUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.castle.fortress.admin.orders.entity.GoodsOrderEntity;
import com.castle.fortress.admin.orders.dto.GoodsOrderDto;
import com.castle.fortress.admin.orders.mapper.GoodsOrderMapper;
import com.castle.fortress.admin.orders.service.GoodsOrderService;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Map;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import java.util.List;

/**
 * 订单表 服务实现类
 *
 * @author Mgg
 * @since 2023-01-13
 */
@Service
public class GoodsOrderServiceImpl extends ServiceImpl<GoodsOrderMapper, GoodsOrderEntity> implements GoodsOrderService {


    @Autowired
    private MemberGoodsCartService memberGoodsCartService;
    @Autowired
    private GoodsOptionService goodsOptionService;

    @Autowired
    private GoodsOrderItemService goodsOrderItemService;

    @Autowired
    private SaleCouponDataService saleCouponDataService;

    @Autowired
    private SaleCouponService saleCouponService;
    /**
    * 获取查询条件
    * @param goodsOrderDto
    * @return
    */
    public QueryWrapper<GoodsOrderEntity> getWrapper(GoodsOrderDto goodsOrderDto){
        QueryWrapper<GoodsOrderEntity> wrapper= new QueryWrapper();
        if(goodsOrderDto != null){
            GoodsOrderEntity goodsOrderEntity = ConvertUtil.transformObj(goodsOrderDto,GoodsOrderEntity.class);
            wrapper.like(StrUtil.isNotEmpty(goodsOrderEntity.getOrderNumber()),"order_number",goodsOrderEntity.getOrderNumber());
            wrapper.like(StrUtil.isNotEmpty(goodsOrderEntity.getProdName()),"prod_name",goodsOrderEntity.getProdName());
            wrapper.eq(goodsOrderEntity.getMemberId() != null,"member_id",goodsOrderEntity.getMemberId());
            wrapper.eq(goodsOrderEntity.getOrderStatus() != null,"order_status",goodsOrderEntity.getOrderStatus());
            wrapper.eq(goodsOrderEntity.getOrderInsideStatus() != null,"order_inside_status",goodsOrderEntity.getOrderInsideStatus());
            wrapper.like(StrUtil.isNotEmpty(goodsOrderEntity.getSerial()),"serial",goodsOrderEntity.getSerial());
            wrapper.eq(goodsOrderEntity.getPayType() != null,"pay_type",goodsOrderEntity.getPayType());
            wrapper.eq(StrUtil.isNotEmpty(goodsOrderEntity.getChannel()),"channel",goodsOrderEntity.getChannel());
            wrapper.eq(goodsOrderEntity.getShopId() != null,"shop_id",goodsOrderEntity.getShopId());
            wrapper.orderByDesc("create_time");
        }
        return wrapper;
    }


    @Override
    public IPage<GoodsOrderDto> pageGoodsOrder(Page<GoodsOrderDto> page, GoodsOrderDto goodsOrderDto) {
        QueryWrapper<GoodsOrderEntity> wrapper = getWrapper(goodsOrderDto);
        Page<GoodsOrderEntity> pageEntity = new Page(page.getCurrent(), page.getSize());
        Page<GoodsOrderEntity> goodsOrderPage=baseMapper.selectPage(pageEntity,wrapper);
        Page<GoodsOrderDto> pageDto = new Page(goodsOrderPage.getCurrent(), goodsOrderPage.getSize(),goodsOrderPage.getTotal());
        pageDto.setRecords(ConvertUtil.transformObjList(goodsOrderPage.getRecords(),GoodsOrderDto.class));
        return pageDto;
    }

    @Override
    public IPage<GoodsOrderDto> pageGoodsOrderExtends(Page<GoodsOrderDto> page, GoodsOrderDto goodsOrderDto){
        Map<String,Long> pageMap = BizCommonUtil.getPageParam(page);
        GoodsOrderEntity goodsOrderEntity = ConvertUtil.transformObj(goodsOrderDto,GoodsOrderEntity.class);
        List<GoodsOrderEntity> goodsOrderList=baseMapper.extendsList(pageMap,goodsOrderEntity);
        Long total = baseMapper.extendsCount(goodsOrderEntity);
        Page<GoodsOrderDto> pageDto = new Page(page.getCurrent(), page.getSize(),total);
        pageDto.setRecords(ConvertUtil.transformObjList(goodsOrderList,GoodsOrderDto.class));
        return pageDto;
    }
    @Override
    public GoodsOrderDto getByIdExtends(Long id){
        GoodsOrderEntity  goodsOrderEntity = baseMapper.getByIdExtends(id);
        return ConvertUtil.transformObj(goodsOrderEntity,GoodsOrderDto.class);
    }

    @Override
    public List<GoodsOrderDto> listGoodsOrder(GoodsOrderDto goodsOrderDto){
        QueryWrapper<GoodsOrderEntity> wrapper = getWrapper(goodsOrderDto);
        List<GoodsOrderEntity> list = baseMapper.selectList(wrapper);
        return ConvertUtil.transformObjList(list,GoodsOrderDto.class);
    }

    @Override
    public GoodsOrderDto saveOrder(GoodsOrderDto goodsOrderDto) {
        //判断订单内商品不为空
        if (goodsOrderDto.getGoodsList() == null || goodsOrderDto.getGoodsList().size() == 0){
            throw new BizException(GlobalRespCode.DB_DATA_ERROR);
        }
        GoodsOrderEntity orderEntity = ConvertUtil.transformObj(goodsOrderDto , GoodsOrderEntity.class);
        //状态改为待支付
        orderEntity.setOrderStatus(OrderStatusEnum.WAIT_PAY.getCode());
        orderEntity.setOrderInsideStatus(OrderInsideStatusEnum.WAIT_PAY.getCode());
        // 生成订单编号
        orderEntity.setOrderNumber(getOrderNumber());
        //保存订单
        save(orderEntity);
        //保存订单内商品列表
//        //用来删除购物车内商品ID用的ID列表
        List<Long> cartIdList = new ArrayList<>();
        //计算订单总价格
        BigDecimal orderAmount = new BigDecimal(0);
        //根据 商品的价格和数量 计算总价
        List<GoodsOrderItemEntity> goodsList = ConvertUtil.transformObjList(goodsOrderDto.getGoodsList(),GoodsOrderItemEntity.class);
        for (GoodsOrderItemEntity goods: goodsList) {
            System.err.println("goods?:"+goods);
            //根据ID 获取商品的价格和数量  计算  并与传过来的总数判断
            goods.setId(null);
            goods.setOrderNumber(orderEntity.getId());
            if (goods.getCartId()!=null) { //购物车的ID不为空,删除购物车时使用
                cartIdList.add(goods.getCartId());
            }

            //TODO 获取该商品的价格(根据规格ID+商品ID)          乘  数量 //单商品总价格 单价X数量
            QueryWrapper<GoodsOptionEntity> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("goods_id",goods.getGoodsId());
            String[] ids = goods.getSpec().split(",");
            for (String id : ids) {
                System.err.println("id:"+id);
                if (StrUtil.isNotEmpty(id)) {
                    queryWrapper.apply("INSTR(specs,"+id+")");
                }
            }
            GoodsOptionEntity goodsOption = goodsOptionService.getOne(queryWrapper);
            System.err.println("goodsOption:"+goodsOption);
            //购买数量
            BigDecimal num = new BigDecimal(goods.getGoodsCount());
            //商品现价
            BigDecimal marketPrice = new BigDecimal(goodsOption.getMarketPrice());
            //当前商品总价
            BigDecimal totalPrice = marketPrice.multiply(num);
            //商品实际单价
            goods.setGoodsPrice(marketPrice);
            //实付单价
            goods.setGoodsRealPrice(marketPrice);
            //总价
            goods.setGoodsTotalAmount(totalPrice);
            orderAmount = orderAmount.add(totalPrice);
        }
        //订单的原价
        orderEntity.setPrice(orderAmount);
        orderEntity.setOldPrice(orderAmount);
        //判断是否用优惠券了，根据优惠券的折扣 减去对应的价格
        SaleCouponEntity saleCoupon = new SaleCouponEntity();
        if (goodsOrderDto.getCouponId() != null){
            // 根据优惠券ID 获取对应的优惠券信息 该会员领取的 券ID为对应ID 状态为未使用的
            QueryWrapper<SaleCouponDataEntity> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("member_id",goodsOrderDto.getMemberId());
            queryWrapper.eq("id",goodsOrderDto.getCouponId());
            queryWrapper.eq("status", CouponStatusEnum.UNUSED.getCode());
            SaleCouponDataEntity saleCouponData = saleCouponDataService.getOne(queryWrapper);
            if (saleCouponData == null){
                //TODO 选择的优惠券ID 没有对应信息 或已经被使用
                throw new BizException("选择的优惠券没有对应信息或已经被使用");
            }
            // 根据券ID 获取对应券信息
            saleCoupon = saleCouponService.getById(saleCouponData.getCouponId());

            //判断满多少可用. 订单价格是否已满足使用条件  等于0 或者( 不等于0 并且 订单价格大于等于满xx可用金额) 是可用的
            if (saleCoupon.getEnough().compareTo(BigDecimal.ZERO) == 0 || (saleCoupon.getEnough().compareTo(BigDecimal.ZERO) !=0 && orderAmount.compareTo(saleCoupon.getEnough()) > -1)){
                //判断是满减券还是折扣券
                if (CouponBackTypeEnum.PAYMENT.getCode().equals(saleCoupon.getBackType())){
                    //立减
                    BigDecimal deduct = new BigDecimal(saleCoupon.getDeduct());
                    orderEntity.setCouponAmount(deduct);
                    orderEntity.setPrice(orderAmount.subtract(deduct));
                }else if (CouponBackTypeEnum.ORDER.getCode().equals(saleCoupon.getBackType())){
                    // 商品总价 乘 折扣率
                    //折扣率
                    BigDecimal discount = new BigDecimal(saleCoupon.getDiscount());
                    //总价 乘 折扣率 为用券之后的实际支付金额
                    BigDecimal price = orderAmount.multiply(discount).setScale(2,BigDecimal.ROUND_HALF_UP);
                    orderEntity.setPrice(price);
                    orderEntity.setCouponAmount(orderAmount.subtract(price));
                }

                // 如果 用券了 给订单内每一项商品减去对应价格 / 减去的价格对应 按比例 给每个商品减对应价格
                //券后价格
                BigDecimal newAmount = orderEntity.getPrice();
                //券后金额 除 原价格 得到优惠的价格比例
                BigDecimal percentage = newAmount.divide(orderEntity.getOldPrice(),4,BigDecimal.ROUND_HALF_UP);//价格比例,保留四位小数  如:0.96 = 96.00%  0.9632 = 96.32%
                for (int i = 0; i < goodsList.size(); i++) {
                    GoodsOrderItemEntity goods = goodsList.get(i);
                    //购买数量
                    BigDecimal goodsNumber = new BigDecimal(goods.getGoodsCount());
                    if (i==goodsList.size()){
                        //如果是最后一条了 /避免出现都用比例乘价格还取2位小数  出现或多或少 几分钱 的问题
                        //商品实际单价  = 总价剩余金额 / 商品数量
                        BigDecimal goodsActualPrice = newAmount.divide(goodsNumber).setScale(2,BigDecimal.ROUND_HALF_UP);
                        //修改订单内商品实际单价
                        goods.setGoodsRealPrice(goodsActualPrice);
                        goods.setGoodsTotalAmount(newAmount);
                    }else{
                        //原单价
                        BigDecimal goodsOriginalPrice = goodsList.get(i).getGoodsPrice();
                        //商品实际单价 = 原单价 X 改价比例  优惠后的价格
                        BigDecimal goodsActualPrice = percentage.multiply(goodsOriginalPrice);
                        //实际总价格 = 实际单价 X 数量 订单商品单商品改价后的总价  四舍五入保留两位小数
                        BigDecimal goodsPayPrice = goodsActualPrice.multiply(goodsNumber).setScale(2,BigDecimal.ROUND_HALF_UP);
                        //总价剩余金额  新总价 减 单商品 总价
                        newAmount = newAmount.subtract(goodsPayPrice);
                        //修改订单内商品 商品实付单价
                        goods.setGoodsRealPrice(goodsActualPrice);
                        goods.setGoodsTotalAmount(goodsPayPrice);
                    }
                }
                //TODO 将优惠券改为已使用
            }
            else{
                //TODO 优惠券不满足使用条件
                throw new BizException("优惠券不满足使用条件");
            }
        }
        updateById(orderEntity);
        //保存订单内商品详情
        goodsOrderItemService.saveBatch(goodsList);
        //TODO 清除购物车中的商品 delete cartIdList memberId
        if (cartIdList.size()>0){
            QueryWrapper<MemberGoodsCartEntity> wrapper= new QueryWrapper();
            wrapper.in("id",cartIdList);
            memberGoodsCartService.remove(wrapper);
        }
        goodsOrderDto = ConvertUtil.transformObj(orderEntity, GoodsOrderDto.class);
        goodsOrderDto.setGoodsList(ConvertUtil.transformObjList(goodsList,GoodsOrderItemDto.class));
        return goodsOrderDto;
    }

    /**
     * 生成订单号
     * @return
     */
    public String getOrderNumber() {
        //生成订单编号
        SimpleDateFormat sdf =new SimpleDateFormat("yyyyMMddHHmmssSSS");
        return "SH"+sdf.format(new Date());
    }

}

